package com.yp.infrastructure.mvc.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import com.yp.infrastructure.common.exception.ErrorMessageUtils;
import com.yp.infrastructure.mvc.exception.EnumErrorMessage;
import com.yp.infrastructure.mvc.exception.MvcException;
import com.yp.infrastructure.mvc.model.ResultSet;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

import java.util.Date;

@Slf4j
@Configuration
@ControllerAdvice
public class ResponseBodyFilter implements ResponseBodyAdvice<Object> {


    /**
     * 需要忽略的地址
     */
    private static final String[] ignores = new String[]{
            //过滤swagger相关的请求的接口，不然swagger会提示base-url被拦截
            "api",
            "v3",
            "actuator",
            "swagger",
    };

    private boolean ignoring(String uri) {
        for (String string : ignores) {
            if (uri.contains(string)) {
                return true;
            }
        }
        return false;
    }


    @Override
    public boolean supports(@NonNull MethodParameter returnType, @NonNull Class converterType) {
        //return false;
        return converterType == FastJsonHttpMessageConverter.class
                || converterType == StringHttpMessageConverter.class
                || converterType == MappingJackson2HttpMessageConverter.class;
    }

    @Override
    public Object beforeBodyWrite(Object body,
                                  @Nullable MethodParameter returnType,
                                  @NonNull MediaType selectedContentType,
                                  @NonNull Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  @NonNull ServerHttpRequest request,
                                  @NonNull ServerHttpResponse response) {

        /* 不支持直接返回数值类型 */
        if (body instanceof Number) throw new MvcException(EnumErrorMessage.UNSUPPORTED_RESP_TYPE);
        ResultSet rs = new ResultSet();
        rs.setErrorMessage(ErrorMessageUtils.toErrorMessage(EnumErrorMessage.SUCCESS));
        /* 空值直接返回*/
        if (null == body) return JSON.toJSONString(rs);
        if (body instanceof ResultSet) return body;
        /* 设置返回值 */
        if (ObjectUtils.isNotEmpty(body)) rs.setData(body);
        if (body instanceof String || body instanceof Date) {
            return JSON.toJSONString(rs);
        }
        return rs;
    }


}
